package DB;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Vector;


public class Table extends RAQuery{

		private Vector<String> key;
		private Vector<Double> prob;
		private Vector<Vector<String>> tuples;
		private Vector<String> titles;
		private String name;
		private double totalProb;
				
	

/*
 * Constructor for creating a new Table
 * while computing the safe plan algorithm
 */
		
		public Table(String name, Vector<String> key, Vector<Double> prob,
				Vector<Vector<String>> tuples, Vector<String> titles, double totalProb) {
			this.name = name;
			this.key = key;
			this.prob = prob;
			this.tuples = tuples;
			this.titles = titles;
			this.totalProb = totalProb;
		
		}
		
		/*
		 * Constructor for the first time
		 */	
		public Table(String name, Vector<String> key,Vector<String> titles, double prob) {

			this.name = name;
			this.key = key;
			this.prob = new Vector<Double>();
			this.tuples = new Vector<Vector<String>>();
			this.titles = titles;
			this.totalProb = prob;

		}
		
/*
 * @see DB.RAQuery#compute()
 * Because this is the computation of the stop condition
 * it returns the Table itself
 */
		@Override
		public Table compute() {
			return this;
		}
		
/*
 * return a specific tuple - by its index - from the Table
 */
		public Vector<String> getTuple(int i) {
			return tuples.elementAt(i);
		}
/*
 * Adds the probability column to the tuple
 */
		public void addTuple(Vector<String> tuple, double p) {
			tuples.addElement(tuple);	
			this.prob.add(new Double(p));
		}
/*
 * returns the probability in the wanted index
 * only in case the index is valid and it is not one
 * else - returns 1 		
 */
		public double getTupleProp(int i) {
			if(prob != null && prob.size() > i)
				return prob.elementAt(i).doubleValue();
			return 1;
		}

/*
 * Sets the probability the tuple in the right
 * index in the Table
 */
		public void setTupleProb(int index, double tupleProb) {
			if (index < prob.size())
				prob.set(index, new Double(tupleProb));	
		}

/*
 * Get the fields which are not keys		
 */
		public Vector<String> getNonKey() {
			Vector<String> ans = new Vector<String>();
			for (int i = 0; i < titles.size(); i++)
				if (!key.contains(titles.elementAt(i)))
					ans.add(titles.elementAt(i));
			return ans;
		}

/*
 * Check if the Table contains the tuple
 */
		public boolean contains(Vector<String> tuple) {
			return tuples.contains(tuple);
		}




		
		public double getTotalProb() {
			return this.totalProb;
		}

//*****************************************//
/*			Help Printing Functions		   */
//*****************************************//
	

		public void print() {
			System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
			System.out.println("Table:" + name);
			System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
			for(String title : titles)
				System.out.print(title + "\t\t");
			System.out.println();
			int i = 0;
			for(Vector<String> tuple : tuples){
				for(String value : tuple)
					System.out.print(value + "\t\t");
				System.out.println(prob.elementAt(i));
				i++;
				System.out.println();
			}
		}
		
		public void printToFile(BufferedWriter out) throws IOException {
			out.write("~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
			out.write("Table:" + name + "\n");
			out.write("~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
			for(String title : titles)
				out.write(title + "\t\t");
			out.write("\n");
			int i = 0;
			for(Vector<String> tuple : tuples){
				for(String value : tuple)
					out.write(value + "\t\t");
				out.write(this.prob.elementAt(i).toString());
				i++;
				out.write("\n");
			}
			
		}
		
		public Vector<Vector<String>> getContent(){
			Vector<Vector<String>> ans = new Vector<Vector<String>>();
			for(int i = 0; i< this.getSize(); i++){
				Vector<String> tTuple = copyTuple(this.tuples.elementAt(i));
				tTuple.add(this.prob.elementAt(i).toString());
				ans.add(tTuple);
			}
			return ans;
		}

		private Vector<String> copyTuple(Vector<String> t) {
			Vector<String> tTuple = new Vector<String>();
			for(String s : t)
				tTuple.add(s);
			return tTuple;
		}
		
//*********************************//
/*		Getters & Setters		   */
//*********************************//	
		
		public int getSize() {
			return tuples.size();
		}
		
		public Vector<String> getKey() {
			Vector<String> ans = new Vector<String>();
			for(String s : this.key)
				ans.add(s);
			return ans;

		}

		public void setKey(Vector<String> key) {
			this.key = key;
		}
		
		public Vector<String> getTitles() {
			Vector<String> ans = new Vector<String>();
			for(String s : this.titles)
				ans.add(s);
			return ans;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}
		

}
